package com.yh.workbill.network;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.yh.workbill.model.Company;
import com.yh.workbill.model.Count;
import com.yh.workbill.model.LoginSuccess;
import com.yh.workbill.model.ResponseMsg;
import com.yh.workbill.model.UseCompany;
import com.yh.workbill.model.WorkBill;
import com.yh.workbill.model.WorkBillCount;
import com.yh.workbill.model.WorkDevices;
import com.yh.workbill.utils.Config;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class OkHttpService {
    private static final String ACCESS_SERVER_FAILURE = "网络不给力";
    private static final String RESPONSE_OBJECT_IS_NULL = "服务器返回数据错误";
    private static final String RESPONSE_PAYLOAD_IS_NULL = "服务器无数据返回";

    private static OkHttpService instance;
    public static final OkHttpClient okHttpClient;
    private static final Retrofit.Builder retrofitBuilder;
    private static final Gson gsonFormat = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:SSS").create();

    static {
        okHttpClient = new OkHttpClient.Builder()
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .connectTimeout(15, TimeUnit.SECONDS)
                .build();

        retrofitBuilder = new Retrofit.Builder()
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(gsonFormat));

        //http 证书问题
        TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }};
        try {
            SSLContext ssl = SSLContext.getInstance("SSL");
            ssl.init(null, trustManagers, new SecureRandom());

            HttpsURLConnection.setDefaultSSLSocketFactory(ssl.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }

    }

    /**
     * API服务接口
     */
    private ApiService apiService;


    public static synchronized OkHttpService getInstance() {
        if (instance == null) {
            instance = new OkHttpService();
        }
        return instance;
    }

    public OkHttpService() {
        apiService = retrofitBuilder.baseUrl(Config.BASEHTTP).build().create(ApiService.class);
    }

    private <T> Callback<ResponseMsg<T>> createRetrofitCallback(BaseCallback callback) {
        Callback<ResponseMsg<T>> responseCallback = new Callback<ResponseMsg<T>>() {
            @Override
            public void onResponse(Call<ResponseMsg<T>> call, Response<ResponseMsg<T>> response) {
                if (response != null) {
                    ResponseMsg<T> body = response.body();
                    if (body != null) {
                        callback.accessSuccess(body.getCode(), body.getMessage(), body.getData());
                    } else {
                        callback.accessFailure(RESPONSE_PAYLOAD_IS_NULL);
                    }
                } else {
                    callback.accessFailure(RESPONSE_OBJECT_IS_NULL);
                }
            }

            @Override
            public void onFailure(Call<ResponseMsg<T>> call, Throwable t) {
                callback.accessFailure(t.getMessage());
            }
        };
        return responseCallback;
    }


    public void login(String phone, String pwd, BaseCallback<LoginSuccess> callback) {
        Call<ResponseMsg<LoginSuccess>> login = apiService.login(phone, pwd);
        login.enqueue(createRetrofitCallback(callback));
    }

    public void checkToken(String token, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> checkToken = apiService.checkToken(token);
        checkToken.enqueue(createRetrofitCallback(callback));
    }

    public void getAllCompany(String user_uuid, int pageindex, int pagenumber, BaseCallback<List<Company>> callback) {
        Call<ResponseMsg<List<Company>>> call = apiService.allCompany(user_uuid, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void getAllUnitCompany(String user_uuid, int pageindex, int pagenumber, BaseCallback<List<UseCompany>> callback) {
        Call<ResponseMsg<List<UseCompany>>> call = apiService.allUnitCompany(user_uuid, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void getWorkBill(String user_uuid, int pageindex, int pagenumber, BaseCallback<List<WorkBill>> callback) {
        Call<ResponseMsg<List<WorkBill>>> call = apiService.workbills(user_uuid, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void addWorkBill(String user_uuid,
                            String work_time,
                            String work_unit,
                            String work_content,
                            String work_car_number,
                            String work_device,
                            double work_use_time,
                            String company_name,
                            double work_time_price, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.AddWorkBill(
                user_uuid, work_time, work_unit, work_content, work_car_number, work_device, work_use_time, company_name,
                work_time_price
        );
        call.enqueue(createRetrofitCallback(callback));
    }

    public void getDevices(BaseCallback<List<WorkDevices>> callback) {
        Call<ResponseMsg<List<WorkDevices>>> call = apiService.getDevices();
        call.enqueue(createRetrofitCallback(callback));
    }

    public void updateWorkBill(
            String uuid,
            String user_uuid,
            String work_time,
            String work_unit,
            String work_content,
            String work_car_number,
            String work_device,
            double work_use_time,
            String company_name,
            double work_time_price, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.UpdataWorkBill(uuid,
                user_uuid, work_time, work_unit, work_content, work_car_number, work_device, work_use_time, company_name,
                work_time_price
        );
        call.enqueue(createRetrofitCallback(callback));
    }

    public void delWorkBill(String uuid, String user_uuid, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.delWorkBill(uuid, user_uuid);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void getCounts(String user_uuid, int pageindex, int pagenumber, BaseCallback<List<Count>> callback) {
        Call<ResponseMsg<List<Count>>> call = apiService.getCounts(user_uuid, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void getWorkBillCount(String user_uuid, BaseCallback<WorkBillCount> callback) {
        Call<ResponseMsg<WorkBillCount>> call = apiService.getWorkBillCount(user_uuid);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void postAddCompanyName(String user_uuid, String company_name, String company_address, String company_phone, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.addCompanyName(user_uuid, company_name, company_address, company_phone);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void postAddUnitCompanyName(String user_uuid, String work_use_company, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.addUnitCompanyName(user_uuid, work_use_company);
        call.enqueue(createRetrofitCallback(callback));
    }


    public void getSearch(String user_uuid, String companyname, String year, String month, int pageindex, int pagenumber, BaseCallback<List<WorkBill>> callback) {
        Call<ResponseMsg<List<WorkBill>>> call = apiService.getSearch(user_uuid, companyname, year, month, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void getSearchCountInfo(String user_uuid, String companyname, String unitname, String year, String month, int pageindex, int pagenumber, BaseCallback<List<WorkBill>> callback) {
        Call<ResponseMsg<List<WorkBill>>> call = apiService.getCountInfo(user_uuid, companyname, unitname, year, month, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }


    public void postSearchCountInfo(String user_uuid,
                                    String phone,
                                    String json,
                                    String year,
                                    String month,
                                    String companyname,
                                    String unitname,
                                    int pageindex,
                                    int pagenumber, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.postExcelFile(
                user_uuid, phone, json, year, month, companyname, unitname, pageindex, pagenumber);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void delCompany(String user_uuid, String uuid, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.postDelCompany(user_uuid, uuid);
        call.enqueue(createRetrofitCallback(callback));
    }

    public void delUseCompany(String user_uuid, String uuid, BaseCallback<String> callback) {
        Call<ResponseMsg<String>> call = apiService.postDelUseCompany(user_uuid, uuid);
        call.enqueue(createRetrofitCallback(callback));
    }
}

